#if 1
#define _XOPEN_SOURCE  1
#define _XOPEN_SOURCE_EXTENDED 1
#define _SVID_SOURCE  1
#define _POSIX_SOURCE  1
#define _BSD_SOURCE  1
#endif
#include <header.h>
#include "Constants.h"
#include "Connection.h"
#include "TireTree.h"
#include "Global.h"
#include "PublicUtils.h"
#include "Filter.h"
#include "CMDMapper.h"
#include "ResponseHeader.h"
#include "ThreadPool.h"


/**
 * @attention 缺陷：token，需要保存到内存中，不应该每次都读取文件，但是使用calloc保存可能会有double free的风险，
 * 所以暂时先读取文件
 * 
 * @bug 所有临界区的变量都必须加锁
*/
int main(void){
	
	initPool(&pool);
	
    int socket_fd;
    SocketDriver(&socket_fd);

	int epoll_fd = epoll_create(1);
	addEpoll(epoll_fd, STDIN_FILENO);
	addEpoll2(epoll_fd, socket_fd);

	initTire();
	
	printf("请输入:login(登录),register(注册),ctrl+c(退出)\n");

	bool manbaOUt = true;
	while(manbaOUt){
		struct epoll_event list[5];
		int epoll_num = epoll_wait(epoll_fd, list, 5, -1);

		for (int i = 0; i < epoll_num; i++){
			/* 若服务端已经close()，则客户端也必须关闭 */
			if (list[i].events & (EPOLLRDHUP | EPOLLHUP)) {
                printf("Server closed connection\n");
				manbaOUt = false;
				break;

            }else if(list[i].data.fd == STDIN_FILENO){
		
				memset(parameter, 0, sizeof(parameter));
				fgets(parameter, sizeof parameter, stdin);
				int ret = handleCommand(&command, parameter);

				if(ret == 1){		
					/* 短命令 */
					requestShortCommand(socket_fd, command, parameter);
				}else if(ret == 2){
					/* 长命令 */
					requestLongCommand(command);
				}

			}else{
				ResponseHeader header;
				memset(&header, 0, sizeof(ResponseHeader));
				
				/* 接收服务端响应头 */
				int ret = recvResponseHeader(socket_fd, &header);
				if(ret == 0){
					printf("What Can I Say ? Manba Out\n");
					manbaOUt = false;
					break;
				}
				resolve(socket_fd, command, &header);
			}
		}
	}


	destoryPool(&pool);
	close(socket_fd);
	return 0;
}
